home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / mtl100je.zip / BUFFERS.H < prev    next >
C/C++ Source or Header  |  1993-05-06  |  5KB  |  139 lines

  1. //--------------------------------------------------------------------------
  2. //
  3. //      BUFFERS.H: header file for DOSMonitor-based bounded buffer.
  4. //      Copyright (c) J.English 1993.
  5. //      Author's address: je@unix.brighton.ac.uk
  6. //
  7. //      Permission is granted to use copy and distribute the
  8. //      information contained in this file provided that this
  9. //      copyright notice is retained intact and that any software
  10. //      or other document incorporating this file or parts thereof
  11. //      makes the source code for the library of which this file
  12. //      is a part freely available.
  13. //
  14. //--------------------------------------------------------------------------
  15. //
  16. //      Revision history:
  17. //      1.0     March 1993      Initial coding
  18. //
  19. //--------------------------------------------------------------------------
  20.  
  21. #ifndef __BUFFERS_H
  22. #define __BUFFERS_H
  23.  
  24. #include "threads.h"
  25.  
  26. //--------------------------------------------------------------------------
  27. //
  28. //      Class BoundedBuffer.
  29. //
  30. //      This is a template for a DOSMonitor-based bounded buffer.
  31. //      The constructor requires the size of the buffer as a parameter.
  32. //      The member functions "get" and "put" allow individual data items
  33. //      to be taken out of and put into the buffer.  The member function
  34. //      "close" allows the buffer to be closed against further use.  The
  35. //      member function "items" returns the number of items currently in
  36. //      the buffer.
  37. //
  38. template<class T> class BoundedBuffer : public DOSMonitor
  39. {
  40.   public:
  41.     BoundedBuffer (unsigned n)  : buffer(new T[n]), buffersize(n),
  42.                                   count(0), inptr(0), outptr(0), closed(0)
  43.                                 { }
  44.     ~BoundedBuffer ()           { delete [] buffer; }
  45.  
  46.     unsigned items ()           { return count; }
  47.  
  48.     int get (T& item);          // get an item from the buffer
  49.     int put (const T& item);    // put an item into the buffer
  50.     void close ();              // close buffer against further use
  51.  
  52.   private:
  53.     DOSMonitorQueue full;
  54.     DOSMonitorQueue empty;
  55.     T* buffer;
  56.     unsigned buffersize;
  57.     unsigned count;
  58.     unsigned inptr;
  59.     unsigned outptr;
  60.     unsigned closed;
  61. };
  62.  
  63. //--------------------------------------------------------------------------
  64. //
  65. //      BoundedBuffer::get.
  66. //
  67. //      Get an item from the buffer.  The thread will be suspended on the
  68. //      "empty" queue as long as the buffer is empty or until the buffer
  69. //      is closed.  If the buffer is closed, the function will return 0.
  70. //      Otherwise, the next item is extracted and the "inptr" is moved
  71. //      to point to the next item.  Finally, any threads waiting while the 
  72. //      buffer is full are resumed (since there is now an empty space in
  73. //      the buffer) and the value 1 is returned to indicate success.
  74. //
  75. template <class T> int BoundedBuffer<T>::get (T& item)
  76. {
  77.     lock ();
  78.     while (count == 0 && !closed)
  79.         suspend (empty);        // await non-empty buffer
  80.     if (count != 0)
  81.     {   item = buffer [inptr++];
  82.         inptr %= buffersize;
  83.         count--;
  84.         resume (full);          // awaken threads waiting for non-full buffer
  85.     }
  86.     unlock ();
  87.     return !closed;
  88. }
  89.  
  90.  
  91. //--------------------------------------------------------------------------
  92. //
  93. //      BoundedBuffer::put.
  94. //
  95. //      Put an item into the buffer.  The thread will be suspended on the
  96. //      "full" queue as long as the buffer is empty or until the buffer
  97. //      is closed.  If the buffer is closed, the function will return 0.
  98. //      Otherwise, the item is stored in the next available space and
  99. //      "outptr" is moved to point to the next free space.  Finally,
  100. //      any threads waiting while the buffer was empty are resumed (since
  101. //      there is now an item in the buffer) and the value 1 is returned
  102. //      to indicate success.
  103. //
  104. template <class T> int BoundedBuffer<T>::put (const T& item)
  105. {
  106.     lock ();
  107.     while (count == buffersize && !closed)
  108.         suspend (full);         // await non-full buffer
  109.     if (count != buffersize)
  110.     {   buffer [outptr++] = item;
  111.         outptr %= buffersize;
  112.         count++;
  113.         resume (empty);         // awaken threads waiting for non-empty buffer
  114.     }
  115.     unlock ();
  116.     return !closed;
  117. }
  118.  
  119. //--------------------------------------------------------------------------
  120. //
  121. //      BoundedBuffer::close.
  122. //
  123. //      This function closes the buffer against further use.  The "closed"
  124. //      flag is set and any suspended threads are resumed.  This is to guard
  125. //      against situations where a thread might wait forever for an item
  126. //      which never arrives, which would prevent the program from ever
  127. //      terminating.
  128. //
  129. template <class T> void BoundedBuffer<T>::close ()
  130. {
  131.     lock ();
  132.     closed = 1;
  133.     resume (full);
  134.     resume (empty);
  135.     unlock ();
  136. }
  137.  
  138. #endif
  139.